package com.satan.fmmall.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.satan.fmmall.entity.*;
import com.satan.fmmall.mapper.ProductImgMapper;
import com.satan.fmmall.mapper.ProductMapper;
import com.satan.fmmall.mapper.ProductParamsMapper;
import com.satan.fmmall.mapper.ProductSkuMapper;
import com.satan.fmmall.service.ProductService;
import com.satan.fmmall.vo.PageHelperVo;
import com.satan.fmmall.vo.ProductVo;
import com.satan.fmmall.vo.ResCode;
import com.satan.fmmall.vo.ResultVo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

/**
 * @ClassName ProductServiceImpl
 * @Description TODO
 * @date 2022/4/5 20:59
 * @Version 1.0
 */
@Service
public class ProductServiceImpl implements ProductService {
    @Resource
    private ProductMapper productMapper;
    @Resource
    private ProductImgMapper productImgMapper;
    @Resource
    private ProductSkuMapper productSkuMapper;
    @Resource
    private ProductParamsMapper productParamsMapper;
    @Resource
    private RestHighLevelClient restHighLevelClient;

    @Override
    public ResultVo listRecommendProducts() {
        List<ProductVo> productVos = productMapper.selectRecommendProducts();
        return ResultVo.success(productVos);
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public ResultVo getProductBasicInfo(String productId) {
        //查询商品基本信息
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Product::getProductId, productId);
        queryWrapper.eq(Product::getProductStatus, 1);
        List<Product> products = productMapper.selectList(queryWrapper);
        if (products.size() > 0) {
            //商品图片
            LambdaQueryWrapper<ProductImg> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(ProductImg::getItemId, productId);
            List<ProductImg> productImgs = productImgMapper.selectList(queryWrapper1);
            //商品套餐
            LambdaQueryWrapper<ProductSku> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(ProductSku::getProductId, productId);
            queryWrapper2.eq(ProductSku::getStatus, 1);
            List<ProductSku> productSkus = productSkuMapper.selectList(queryWrapper2);
            HashMap<String, Object> basicInfo = new HashMap<>();
            basicInfo.put("product", products.get(0));
            basicInfo.put("productImgs", productImgs);
            basicInfo.put("productSkus", productSkus);
            return ResultVo.success(basicInfo);
        } else {
            return ResultVo.fail(ResCode.NO_PRODUCT);
        }
    }

    @Override
    public ResultVo getProductParamsById(String productId) {
        LambdaQueryWrapper<ProductParams> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(ProductParams::getProductId,productId);
        ProductParams productParams = productParamsMapper.selectOne(queryWrapper);
        if (productParams!=null) {
            return ResultVo.success(productParams);
        }else {
            return ResultVo.fail(ResCode.NO_PRODUCT_PARAMS);
        }
    }

    @Override
    public ResultVo getProductsByCategoryId(Integer categoryId, Integer pageNum, Integer pageSize) {
        Integer start=(pageNum-1)*pageSize;
        List<ProductVo> productVos = productMapper.selectProductByCategoryId(categoryId, start, pageSize);
        LambdaQueryWrapper<Product> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Product::getCategoryId,categoryId);
        Long count = productMapper.selectCount(queryWrapper);
        Long pageCount=count%pageSize==0?count/pageSize:count/pageSize+1;
        //封装返回数据
        PageHelperVo<ProductVo> pageHelperVo=new PageHelperVo<>(count,pageCount,productVos);
        return ResultVo.success(pageHelperVo);
    }

    @Override
    public ResultVo getProductsByKeyword(String keyword, int pageNum, int pageSize) throws IOException {
        Integer start=(pageNum-1)*pageSize;
        //从ES查询数据
        SearchRequest searchRequest=new SearchRequest("fm_products_index");
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        //查询条件
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery(keyword, "productName","productSkuName"));
        //分页条件
        searchSourceBuilder.from(start);
        searchSourceBuilder.size(pageSize);
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        HighlightBuilder.Field field1=new HighlightBuilder.Field("productName");
        HighlightBuilder.Field field2=new HighlightBuilder.Field("productSkuName");
        highlightBuilder.field(field1);
        highlightBuilder.field(field2);
        highlightBuilder.preTags("<label style='color:red'>");
        highlightBuilder.postTags("</label>");
        searchSourceBuilder.highlighter(highlightBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //封装查询结果
        SearchHits hits = searchResponse.getHits();
        //获取总记录数
        long count = hits.getTotalHits().value;


        //List<ProductVo> productVos = productMapper.selectProductByKeyword(keyword, start, pageSize);
        //LambdaQueryWrapper<Product> queryWrapper=new LambdaQueryWrapper<>();
        //queryWrapper.eq(Product::getCategoryId,keyword);
        //Long count = productMapper.selectCount(queryWrapper);
        //计算总页数
        List<ProductEs> productEsList=new ArrayList<>();
        Long pageCount=count%pageSize==0?count/pageSize:count/pageSize+1;
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            ProductEs productEs = JSONObject.parseObject(sourceAsString, ProductEs.class);
            //获取高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField highlightField1 = highlightFields.get("productName");
            if (highlightField1!=null){
                Text[] fragments = highlightField1.getFragments();
                String productName = Arrays.toString(fragments).replace("[", "").replace("]", "");
                productEs.setProductName(productName);
            }
            HighlightField highlightField2 = highlightFields.get("productSkuName");
            if (highlightField2!=null){
                Text[] fragments = highlightField2.getFragments();
                String productSkuName = Arrays.toString(fragments).replace("[", "").replace("]", "");
                productEs.setProductSkuName(productSkuName);
            }
            productEsList.add(productEs);
        }
        //封装返回数据
        PageHelperVo<ProductEs> pageHelperVo=new PageHelperVo<>(count,pageCount,productEsList);
        return ResultVo.success(pageHelperVo);
    }


}
